using System.Configuration;
using System.Web;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Shinkansen.Configuration
{
    public class MachineKeyCryptoProvider : ICryptoKeyProvider
    {
        private const string _configurationError = "To use StaticResourceManager, you need to declare a <machineKey> section in web.config and generate validationKey and decryptionKey.";
        private static readonly string _key;
        private static readonly string _iv;

        /// <summary>
        /// Initializes the <see cref="MachineKeyCryptoProvider"/> class.
        /// </summary>
        static MachineKeyCryptoProvider ()
        {
            string      webConfigFile = HttpContext.Current.Server.MapPath ("~/web.config");
            XDocument   config = XDocument.Load (webConfigFile);
            XElement    machineKey = config.XPathSelectElement ("/configuration/system.web/machineKey");

            if (machineKey == null)
                throw new ConfigurationErrorsException (_configurationError);


            XAttribute decryptionKeyAttribute = machineKey.Attribute ("decryptionKey");
            XAttribute validationKeyAttribute = machineKey.Attribute ("validationKey");

            if (decryptionKeyAttribute == null || validationKeyAttribute == null)
                throw new ConfigurationErrorsException (_configurationError); 

            _key = decryptionKeyAttribute.Value;
            _iv = validationKeyAttribute.Value;

            if (string.IsNullOrEmpty (_key) || string.IsNullOrEmpty (_iv))
                throw new ConfigurationErrorsException (_configurationError); 
        }

        /// <summary>
        /// Gets the key.
        /// </summary>
        /// <value>The key.</value>
        public string Key
        {
            get { return _key; }
        }

        /// <summary>
        /// Gets the initialization vector (IV).
        /// </summary>
        /// <value>The IV.</value>
        public string IV
        {
            get { return _iv; }
        }
    }
}